﻿#pragma once

#include "precomp.h"
#include "game_object.h"
#include "bullet.h"
#include "resources.h"
#include "renders.h"
#include "sound.h"
#include "patterns.h"
#include "bonus.h"

class Enemy_Appearance;
class Enemy_Path;
class Bonus;

// Хранит выстрелы противника
struct _BulletPattern{
	char launch_type; // 1 - по времени, 2 - по расстоянию, 3 - по триггеру,  0 - паттерн уже отработал своё
	int type; // тип паттерна
	int launch; // значение параметра, по которому запускать
};

// Набор спеллкарт босса
struct _SpellPattern{
	int nonspellhp;
	int spellhp;
	int price;
	CL_String nonspell;
	CL_String spell;
	CL_Vec2<float> start_position; // Исходная позиция, на которую босс перемещается, прежде чем запускать спеллкарту
	float start_speed; // Скорость, с которой перемещаться на исходную позицию
	float start_wait; // Пауза перед запуском спеллкарты
};

class Enemy : public GameObject {
public:
	CL_Vec2<float> move;
	CL_Angle orientation;
	CL_Vec2<int> sprite_size;
	float base_speed;
	float speed;
	int hp; // Жизни
	char alive; // 0 - уничтожен, нужно убирать, 1 - живой
	char dead; // 0 - в живых, 1 - в мёртвых
	char passable; // 1 - игрок проходит сквозь, 0 - сталкивается
	char is_boss; // 0 - Обычный, >=1 - босс
	char bonus_drop;
	int score; // Очки за уничтожение

	unsigned int id;
	unsigned int parent;
	//unsigned int *children;

	int version; // Какая версия из нескольких вариантов раскраски
	int animation_frame;
	float time_from_last_frame;

	// Информация паттернов
	float time_lived;
	float traveled;
	char trigger;
	char shots; // сколько всего выстрелов или спеллкарт
	_BulletPattern bullet_patterns[64];
	void ProcessPatterns();

	float param_float1;
	float param_float2;
	CL_String name;

	Enemy_Appearance *appearance;
	Enemy_Path *path;

	void Render(CL_GraphicContext &gc);
	void RenderDead(CL_GraphicContext &gc);
	void Update(float time);
	void PlayDeadSound();
};

class EnemyBoss : public Enemy{
public:
	int current_spellcard; // Номер пары нонспелл-спелл по счёту
	int current_spellcard_action; // Текущее действие в скрипте спеллкарты
	int spell_hp; // Жизни текущей спеллкарты (как нонспелла так и спелла)
	int current_spell_level; // 0 - nonspell, 1 - spell1, ...
	float spell_time; // Остающееся до конца спеллкарты время
	float action_time; // Время действия текущего действия спеллкарты

	int moving; // босс в движении
	int acting; // босс выполняет действие на месте
	float ukanderu; // парение на месте
	float move_time;
	float act_time;

	float acceleration;

	int have_dialog;
	CL_String dialog_name;

	CL_Vec2f position1;
	CL_Vec2f position2;
	std::vector<_SpellPattern> spell_patterns; // Спеллкарты

	// Данные эффектов на боссе
	int spell_effects_processed;
	int rnd_rings; // количество колечек
	int rnd_ring_index[8]; // Вид кольца
	int rnd_ring_status[8]; // Состояние кольца :
									// 0 - инициализация
									// 1 - рабочее состояние
									// 2 - смена позиции, 3 - убирание
	float rnd_ring_radius[8]; // Размеры колец
	float rnd_ring_width[8]; // Толщина колец
	float rnd_ring_position[8]; // Угловая позиция колец
	float rnd_ring_speed[8]; // Скорость вращения
	float rnd_ring_alpha[8]; // Прозрачность
	float rnd_ring_temp[8]; // Временные параметры
	float rnd_rings_radius_delta; // общий коэффициент размера колец
	CL_Vec2f rnd_rings_center; // центр колец
	Effect spellcard_name_effect;

	void RenderBack(CL_GraphicContext &gc, float time);
	void RenderFront(CL_GraphicContext &gc, float time);
};

class Enemy_Manager{
private:
	std::vector<CL_SharedPtr<Enemy>> enemies;
	std::vector<CL_SharedPtr<Enemy>> dead_enemies;
	unsigned int active_enemies_count;
	unsigned int next_id;

	void LaunchBonus(Enemy* e);
public:
	Enemy_Manager();
	~Enemy_Manager();
	int Create(Enemy &p_enemy_description);
	int Create(EnemyBoss &p_enemy_description);
	void Clear();
	void Update(float time);
	void UpdateDead(float time);
	void Render(CL_GraphicContext &gc, CL_Rect &clip);
	void RenderDead(CL_GraphicContext &gc, CL_Rect &clip);
	void CalculateCollisions();
	void DestroyEnemies(GameObject *canceler);
	void BombEnemies(float time);
	int CollidePlayer();
	CL_Vec2<float> GetClosestEnemyPosition();
	EnemyBoss* GetBoss();
};

extern Enemy_Manager emanager;
